package com.jacky.demo.func;

import android.Manifest;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.support.annotation.NonNull;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.TextView;

import com.jacky.demo.BaseActivity;
import com.jacky.demo.R;
import com.jacky.demo.util.AppUtils;
import com.jacky.demo.util.MD5;
import com.jacky.demo.util.StorageUtil;
import com.jacky.log.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by jacky on 2018/5/10.
 */

public class RecordActivity extends BaseActivity implements View.OnClickListener {

    SurfaceView mSurfaceView;
    TextView mTvTime;
    boolean isRecording;

    MediaRecorder mMediaRecorder;
    Camera mCamera;
    int time = 60 * 60 * 24;//30 seconds

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            time--;
            if(time <= 0) {
                stop();
            } else {
                int h = time / 3600;
                int t = time % 3600;
                int m = t / 60;
                int s = t % 60;
                mTvTime.setText("" + h + ":" + m + ":" + s);
                mTvTime.postDelayed(this, 1000);
            }
        }
    };

    @Override
    protected int getContentView() {
        return R.layout.record_activity;
    }

    @Override
    protected void initCreate() {
        setTitle("视频拍摄");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mSurfaceView = (SurfaceView) findViewById(R.id.surface);
        mTvTime = (TextView) findViewById(R.id.time);
        findViewById(R.id.start).setOnClickListener(this);
        findViewById(R.id.stop).setOnClickListener(this);

        SurfaceHolder holder = mSurfaceView.getHolder();
        holder.setFormat(PixelFormat.TRANSPARENT);
        holder.setFixedSize(1280, 720);
        holder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {}

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                stop();
            }
        });
        // setType必须设置，要不出错.
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        if(AppUtils.isRoot()) {
            showToast("系统已root");
        } else {

        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start :
                AppUtils.requestPermission(this, 1,
                        Manifest.permission.CAMERA,
                        Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE);
                break;
            case R.id.stop :
                stop();
                break;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(requestCode == 1) {
            if(AppUtils.isPermissionOK(this, permissions, grantResults)) {
                start();
            } else {
                showToast("摄像头、录音或者存储权限未开启");
            }
        }
    }

    private void start() {
        if (isRecording) return;
        mCamera = Camera.getNumberOfCameras() == 1 ? Camera.open() : Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        if (mCamera == null) return;
        File output = new File(getFilesDir(), ".11111.mp4");
        try {
            output.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
            showToast("创建文件失败");
            return;
        }

        try {

            mCamera.setDisplayOrientation(90);
            mCamera.unlock();//this very importance

            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.setCamera(mCamera);

            // 这两项需要放在setOutputFormat之前
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

            // Set output file format
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

            // 这两项需要放在setOutputFormat之后
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

            mMediaRecorder.setVideoSize(1280, 720); //720*540; 640*480
//            mMediaRecorder.setVideoFrameRate(25);
            mMediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
            mMediaRecorder.setOrientationHint(90);
            //设置记录会话的最大持续时间（毫秒）
            mMediaRecorder.setMaxDuration(time * 1000);
            mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());

            mMediaRecorder.setOutputFile(output.getPath());
            mMediaRecorder.prepare();
            mMediaRecorder.start();
            isRecording = true;

            runnable.run();
        } catch (Exception e) {
            Logger.e(e);
            showToast("启动失败");
        }
    }

    private void stop() {
        if(isRecording == false) return;
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mMediaRecorder = null;
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
        mTvTime.removeCallbacks(runnable);
        isRecording = false;

        new Thread(new Runnable() {
            @Override
            public void run() {
                File output = new File(getFilesDir(), ".11111.mp4");
                File ooo = new File("/sdcard/11AA/11111.mp4");
                ooo.getParentFile().mkdirs();
                try {
                    ooo.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                FileOutputStream stream = null;
                FileInputStream stream1 = null;
                MessageDigest mdTemp;
                try {
                    stream1 = new FileInputStream(output);
                    stream = new FileOutputStream(ooo);
                    mdTemp = MessageDigest.getInstance("MD5");

                    int i;
                    byte[] bytes = new byte[1024* 100];
                    while (true) {
                        i = stream1.read(bytes);
                        if(i == -1) break;
                        stream.write(bytes,0, i);
                        mdTemp.update(bytes, 0, i);
                    }
                    byte[] b = mdTemp.digest();
                    Logger.e(transferByte2String(b));
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
//                    output.delete();
                    StorageUtil.close(stream);
                    StorageUtil.close(stream1);
                }
                Logger.w(MD5.encryptFile(new File("/sdcard/11AA/11111.mp4")));

            }
        }).start();
    }

    private static final String transferByte2String(byte[] bytes) {
        int k = 0;
        int size = bytes == null ? 0 : bytes.length;
        char str[] = new char[size * 2];

        for (int i = 0; i < size; i++) {
            byte b = bytes[i];
            str[k++] = hexDigits[b >> 4 & 0xf];
            str[k++] = hexDigits[b & 0xf];
        }
        return new String(str);
    }

    private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

}
